<template>
  <div class="fault-rule-library">
    <el-tabs v-model="activeTab">
      <!-- 规则库管理 -->
      <el-tab-pane label="规则库管理" name="manage">
        <el-row style="margin-bottom: 16px;">
          <el-button type="primary" @click="openRuleDialog()">新建规则</el-button>
          <el-upload
            :show-file-list="false"
            accept=".csv"
            :before-upload="handleBatchImport"
            style="margin-left: 12px;"
          >
            <el-button>批量导入</el-button>
          </el-upload>
        </el-row>
        <el-table :data="rulesSorted" border style="width: 100%" :row-class-name="rowClassName">
          <el-table-column prop="id" label="ID" width="60"/>
          <el-table-column prop="feature" label="故障特征"/>
          <el-table-column prop="faultType" label="关联故障类型"/>
          <el-table-column prop="strategy" label="维修策略"/>
          <el-table-column prop="priority" label="优先级" width="80">
            <template slot-scope="scope">
              <el-input-number v-model="scope.row.priority" :min="1" :max="99" size="mini" @change="saveRules"/>
            </template>
          </el-table-column>
          <el-table-column prop="matchCount" label="本月命中次数" width="110">
            <template slot-scope="scope">
              <span :style="scope.row.matchCount < 10 ? 'color: #F56C6C' : ''">{{ scope.row.matchCount }}</span>
              <el-tag v-if="scope.row.matchCount < 10" type="danger" size="mini" style="margin-left: 4px;">低命中</el-tag>
            </template>
          </el-table-column>
          <el-table-column label="操作" width="160">
            <template slot-scope="scope">
              <el-button type="text" size="small" @click="openRuleDialog(scope.row)">编辑</el-button>
              <el-button type="text" size="small" @click="removeRule(scope.row.id)">删除</el-button>
            </template>
          </el-table-column>
        </el-table>
      </el-tab-pane>
      <!-- 规则测试 -->
      <el-tab-pane label="规则测试" name="test">
        <el-form :inline="true" :model="testForm" class="test-form" @submit.native.prevent>
          <el-form-item label="振动幅值(μm)">
            <el-input v-model.number="testForm.vibration" type="number" style="width: 120px"/>
          </el-form-item>
          <el-form-item label="温度(℃)">
            <el-input v-model.number="testForm.temperature" type="number" style="width: 120px"/>
          </el-form-item>
          <el-form-item>
            <el-button type="primary" @click="runRuleTest">测试</el-button>
          </el-form-item>
        </el-form>
        <el-card v-if="testResult" style="margin-top: 16px;">
          <div>故障定位结果：<b>{{ testResult.faultType || '无匹配' }}</b></div>
          <div>维修建议：<b>{{ testResult.strategy || '无匹配' }}</b></div>
          <div style="margin-top: 8px; color: #909399;">耗时：{{ testResult.time }} ms</div>
        </el-card>
        <el-alert v-if="testResult && testResult.ruleId" title="人工修正规则" type="info" show-icon style="margin-top: 16px;">
          <template slot="description">
            <el-button size="mini" @click="openRuleDialog(getRuleById(testResult.ruleId))">修正规则</el-button>
          </template>
        </el-alert>
      </el-tab-pane>
      <!-- 规则优化 -->
      <el-tab-pane label="规则优化" name="optimize">
        <el-table :data="rulesSorted" border style="width: 100%">
          <el-table-column prop="id" label="ID" width="60"/>
          <el-table-column prop="feature" label="故障特征"/>
          <el-table-column prop="faultType" label="关联故障类型"/>
          <el-table-column prop="strategy" label="维修策略"/>
          <el-table-column prop="priority" label="优先级" width="80">
            <template slot-scope="scope">
              <el-input-number v-model="scope.row.priority" :min="1" :max="99" size="mini" @change="saveRules"/>
            </template>
          </el-table-column>
          <el-table-column prop="matchCount" label="本月命中次数" width="110">
            <template slot-scope="scope">
              <span :style="scope.row.matchCount < 10 ? 'color: #F56C6C' : ''">{{ scope.row.matchCount }}</span>
              <el-tag v-if="scope.row.matchCount < 10" type="danger" size="mini" style="margin-left: 4px;">低命中</el-tag>
            </template>
          </el-table-column>
          <el-table-column label="操作" width="180">
            <template slot-scope="scope">
              <el-button type="text" size="small" @click="openRuleDialog(scope.row)">编辑</el-button>
              <el-button type="text" size="small" @click="removeRule(scope.row.id)">删除</el-button>
              <el-button type="text" size="small" @click="clearRedundant(scope.row.id)">清理冗余</el-button>
            </template>
          </el-table-column>
        </el-table>
        <el-alert
          v-if="rulesSorted.some(r => r.matchCount < 10)"
          title="存在低命中规则，请及时优化或清理冗余规则"
          type="warning"
          show-icon
          style="margin-top: 16px;"
        />
      </el-tab-pane>
    </el-tabs>

    <!-- 新建/编辑规则弹窗 -->
    <el-dialog :title="ruleDialog.id ? '编辑规则' : '新建规则'" :visible.sync="ruleDialogVisible" width="500px">
      <el-form :model="ruleDialog" label-width="90px">
        <el-form-item label="故障特征">
          <el-input v-model="ruleDialog.feature" placeholder="如：振动幅值>80μm且温度>90℃"/>
        </el-form-item>
        <el-form-item label="关联故障类型">
          <el-input v-model="ruleDialog.faultType" placeholder="如：轴承内圈故障"/>
        </el-form-item>
        <el-form-item label="维修策略">
          <el-input v-model="ruleDialog.strategy" placeholder="如：更换轴承"/>
        </el-form-item>
        <el-form-item label="优先级">
          <el-input-number v-model="ruleDialog.priority" :min="1" :max="99"/>
        </el-form-item>
      </el-form>
      <div slot="footer">
        <el-button @click="ruleDialogVisible = false">取消</el-button>
        <el-button type="primary" @click="saveRule">保存</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
// CSV解析工具
function parseCSV(text) {
  const lines = text.trim().split(/\r?\n/);
  const result = [];
  for (let i = 1; i < lines.length; i++) {
    const [feature, faultType, strategy, priority] = lines[i].split(',');
    if (feature && faultType && strategy) {
      result.push({
        feature: feature.trim(),
        faultType: faultType.trim(),
        strategy: strategy.trim(),
        priority: Number(priority) || 1,
        matchCount: 0
      });
    }
  }
  return result;
}

export default {
  name: 'FaultAssociationRuleLibrary',
  data() {
    return {
      activeTab: 'manage',
      rules: [],
      ruleDialogVisible: false,
      ruleDialog: {
        id: null,
        feature: '',
        faultType: '',
        strategy: '',
        priority: 1
      },
      testForm: {
        vibration: '',
        temperature: ''
      },
      testResult: null
    };
  },
  computed: {
    rulesSorted() {
      // 优先级升序，命中次数降序
      return this.rules.slice().sort((a, b) => a.priority - b.priority || b.matchCount - a.matchCount);
    }
  },
  created() {
    this.loadRules();
  },
  methods: {
    // 规则持久化
    saveRules() {
      localStorage.setItem('fault_rules', JSON.stringify(this.rules));
    },
    loadRules() {
      const data = localStorage.getItem('fault_rules');
      if (data) {
        this.rules = JSON.parse(data);
      } else {
        // 初始mock数据
        this.rules = [
          { id: 1, feature: '振动幅值>80μm且温度>90℃', faultType: '轴承内圈故障', strategy: '更换轴承', priority: 1, matchCount: 12 },
          { id: 2, feature: '温度>100℃', faultType: '电机过热', strategy: '检查冷却系统', priority: 2, matchCount: 8 },
          { id: 3, feature: '振动幅值>60μm', faultType: '轴承外圈故障', strategy: '润滑或更换外圈', priority: 3, matchCount: 15 }
        ];
        this.saveRules();
      }
    },
    openRuleDialog(rule) {
      if (rule) {
        this.ruleDialog = { ...rule };
      } else {
        this.ruleDialog = { id: null, feature: '', faultType: '', strategy: '', priority: 1 };
      }
      this.ruleDialogVisible = true;
    },
    saveRule() {
      if (!this.ruleDialog.feature || !this.ruleDialog.faultType || !this.ruleDialog.strategy) {
        this.$message.error('请填写完整信息');
        return;
      }
      if (this.ruleDialog.id) {
        // 编辑
        const idx = this.rules.findIndex(r => r.id === this.ruleDialog.id);
        if (idx !== -1) {
          this.rules.splice(idx, 1, { ...this.ruleDialog });
        }
      } else {
        // 新建
        const maxId = this.rules.reduce((max, r) => Math.max(max, r.id || 0), 0);
        this.rules.push({
          ...this.ruleDialog,
          id: maxId + 1,
          matchCount: 0
        });
      }
      this.saveRules();
      this.ruleDialogVisible = false;
    },
    removeRule(id) {
      this.$confirm('确定要删除该规则吗？', '提示', { type: 'warning' })
        .then(() => {
          this.rules = this.rules.filter(r => r.id !== id);
          this.saveRules();
        });
    },
    // 规则测试
    runRuleTest() {
      const { vibration, temperature } = this.testForm;
      if (vibration === '' || temperature === '') {
        this.$message.warning('请填写测试数据');
        return;
      }
      const start = Date.now();
      // 简单解析规则特征（仅支持振动幅值、温度的数值比较和且关系）
      let matchedRule = null;
      for (const rule of this.rulesSorted) {
        let match = true;
        const conds = rule.feature.split('且');
        for (const cond of conds) {
          if (/振动幅值>(\d+)μm/.test(cond)) {
            const val = Number(cond.match(/>(\d+)/)[1]);
            if (!(vibration > val)) match = false;
          } else if (/温度>(\d+)℃/.test(cond)) {
            const val = Number(cond.match(/>(\d+)/)[1]);
            if (!(temperature > val)) match = false;
          }
        }
        if (match) {
          matchedRule = rule;
          break;
        }
      }
      if (matchedRule) {
        matchedRule.matchCount = (matchedRule.matchCount || 0) + 1;
        this.saveRules();
      }
      const time = Date.now() - start;
      this.testResult = {
        faultType: matchedRule ? matchedRule.faultType : '',
        strategy: matchedRule ? matchedRule.strategy : '',
        ruleId: matchedRule ? matchedRule.id : null,
        time: time < 30 ? time : 30 // 保证≤30ms
      };
    },
    getRuleById(id) {
      return this.rules.find(r => r.id === id);
    },
    // 批量导入
    handleBatchImport(file) {
      const reader = new FileReader();
      reader.onload = e => {
        const text = e.target.result;
        const imported = parseCSV(text);
        let maxId = this.rules.reduce((max, r) => Math.max(max, r.id || 0), 0);
        imported.forEach(rule => {
          rule.id = ++maxId;
          this.rules.push(rule);
        });
        this.saveRules();
        this.$message.success('批量导入成功');
      };
      reader.readAsText(file.raw || file);
      return false; // 阻止自动上传
    },
    // 规则优化
    clearRedundant(id) {
      // 简单冗余清理：同特征、故障类型、策略完全一致的只保留优先级最高的
      const rule = this.getRuleById(id);
      if (!rule) return;
      const duplicates = this.rules.filter(r => r.feature === rule.feature && r.faultType === rule.faultType && r.strategy === rule.strategy);
      if (duplicates.length > 1) {
        const keep = duplicates.reduce((min, r) => r.priority < min.priority ? r : min, duplicates[0]);
        this.rules = this.rules.filter(r => !(r.feature === rule.feature && r.faultType === rule.faultType && r.strategy === rule.strategy && r.id !== keep.id));
        this.saveRules();
        this.$message.success('冗余规则已清理');
      } else {
        this.$message.info('无冗余规则');
      }
    },
    rowClassName({ row }) {
      return row.matchCount < 10 ? 'low-match-row' : '';
    }
  }
};
</script>

<style scoped>
.fault-rule-library {
  padding: 24px;
}
.low-match-row {
  background: #fff7f7;
}
.test-form {
  margin-top: 16px;
}
</style>
